<?php
/*
 * Functions for handling HTTP POST requests.
 */

require_once('environment.php');
require_once('lib.php');
require_once('misc.php');
require_once('html.php');
require_once('data_access.php');
require_once('simulation.php');
require_once('paginator.php');

/**
 * Handle posted investment suggestion. If the submitted values fail validation
 * the form is reprinted with the relevant warning messages, otherwise a
 * success message is printed.
 */
function http_post_upcoming_new() {
    global $_CONFIG;

    // Check number of candidate investments has not exceeded limit.
    if (($_CONFIG->simulation_max_candidate - read_num_candidates()) < 1) {
        // TODO Display user friendly notice that limit has been reached.
        http_bad_request();
    }

    // title
    $constraints['title'] = function() use ($_CONFIG) {
            $value = $_POST['title'];
            if (strlen($value) == 0) {
                return 'You didn\'t enter a title';
            }
            if (strlen($value) > $_CONFIG->form_max_title_len) {
                return "Title cannot be longer than $_CONFIG->form_max_title_len characters";
            }
        };

    // description
    $constraints['description'] = function() use ($_CONFIG) {
            $value = $_POST['description'];
            if (strlen($value) == 0) {
                return 'You didn\'t enter a description';
            }
            if (strlen($value) > $_CONFIG->form_max_desc_len) {
                return "Description cannot be longer than $_CONFIG->form_max_desc_len characters";
            }
        };

    // charity name
    $constraints['charity_name'] = function() use ($_CONFIG) {
            $value = $_POST['charity_name'];
            if (strlen($value) == 0) {
                return 'You didn\'t enter a charity name';
            }
            if (strlen($value) > $_CONFIG->form_max_charity_len) {
                return "Charity name cannot be longer than $_CONFIG->form_max_charity_len characters";
            }
        };

    // charity url
    $constraints['charity_url'] = function() use ($_CONFIG) {
            $value = $_POST['charity_url'];
            if (strlen($value) == 0) {
                return 'You didn\'t enter a charity website';
            }
            if (strlen($value) > $_CONFIG->form_max_url_len) {
                return "Website address cannot be longer than $_CONFIG->form_max_url_len characters";
            }
            // quote characters in URLs that will end up as HREF attribute
            // values can lead to XSS attacks. doesn't seem to be a better way
            // of doing this, see:
            // http://bugs.php.net/bug.php?id=51050
            if (!filter_var($value, FILTER_VALIDATE_URL) || strpos($value, '"')) {
                return "Not a valid website address";
            }
        };

    $errors = validate_form_post($constraints);

    // print page HTML
    print_html_head(HEAD_TAB_UPCOMING);
    if ($errors) {
        print_html_investment_form($_POST, $errors);
    } else {
        write_investment($_POST['title'], $_POST['description'],
                         $_POST['charity_name'], $_POST['charity_url'],
                         simulate_username(), time(), simulate_investment_img());
        print_html_modal_msg('Your investment suggestion has been saved', '/upcoming');
    }
    print_html_foot();
}

/**
 * Post a comment to an investment.
 * @param array request regex arguments
 */
function http_post_comment($investment_id) {
    global $_CONFIG;

    // validate form post
    $constraints['content'] = function() use ($_CONFIG) {
            $value = $_POST['content'];
            if (strlen($value) == 0) {
                return 'You didn\'t enter a comment';
            }
            if (strlen($value) > $_CONFIG->form_max_comment_len) {
                return "Comment cannot be longer than $_CONFIG->form_max_comment_len characters";
            }
        };
    $errors = validate_form_post($constraints);

    // read investment data, from either live or upcoming database tables
    if (!$investment = read_investment($investment_id)) {
        http_not_found();
    }

    if ($errors) {

        // rerender form with errors messages
        $args = array($investment_id, $_POST, $errors, false);
        $f = 'print_html_comment_form';
        $response['comment_form_container'] = capture_print($f, $args);
    } else {

        // write comment to database
        $comment = write_comment($investment, simulate_username(),
                                 $_POST['content'], time());

        // render blank form
        $args = array($investment_id);
        $f = 'print_html_comment_form';
        $response['comment_form_container'] = capture_print($f, $args);

        // render new post at top of comments list
        $args = array($comment);
        $f = 'print_html_comment';
        $response['*xlist_container_comments'] = capture_print($f, $args);
    }
    ajax_response($response);
}

/**
 * Record that a user likes an investment suggestion and update the UI
 * accordingly.
 * @param string $investment_id Investment record ID.
 */
function http_post_like($investment_id) {
    
    // check investment exists and is of type candidate
    if (!$investment = read_investment($investment_id)) {
        http_not_found();
    }
    if ($investment['type'] != INVESTMENT_TYPE_CANDIDATE) {
        http_bad_request();
    }

    // simlulate username (for now)
    $username = simulate_username();

    write_vote(TABLE_LIKES, $investment_id, $username);

    // print updated like/dislike HTML component
    $html = capture_print('print_html_like_buttons', array($investment));
    ajax_response(array('likes_box' => $html));
}

/**
 * Record that a user dislikes an investment suggestion and update the UI
 * accordingly.
 * @param string $investment_id Investment record ID.
 */
function http_post_dislike($investment_id) {

    // check investment exists and is of type candidate
    if (!$investment = read_investment($investment_id)) {
        http_not_found();
    }
    if ($investment['type'] != INVESTMENT_TYPE_CANDIDATE) {
        http_bad_request();
    }

    // simlulate username (for now)
    $username = simulate_username();

    write_vote(TABLE_LIKES, $investment_id, $username, -1);

    // print updated like/dislike HTML component
    $html = capture_print('print_html_like_buttons', array($investment));
    ajax_response(array('likes_box' => $html));
}

/**
 * Register a vote for a candidate then display the standard page.
 */
function http_post_vote($investment_id) {

    // verify that investment ID is a valid candidate
    if (!in_array($investment_id, read_candidate_ids(read_this_month()))) {
        http_bad_request();
    }

    // simlulate username (for now)
    $username = simulate_username();

    write_vote(TABLE_VOTES, $investment_id, $username);

    // confirm vote was received
    ajax_response(array('vote_button_'.$investment_id =>
                        '<div class="voted"><span>Voted &#10004;</span></div>'));
}

/**
 * Execute script that performs the vote counting and candidate generation at
 * the end of each month.
 */
function http_post_end_of_month() {
    global $_CONFIG;

    // check the number of allowed 'end of month' invocations per simulation has
    // not been exceeded
    if (get_timeframe() >= $_CONFIG->simulation_max_months) {
        throw new Exception("Simulation cannot exceed $_CONFIG->simulation_max_months month(s)");
    }

    // invoke daemon to perform 'end of month' process
    exec('php /usr/local/src/php/pepandlove-daemon/votecount/main.php -i', $output, $return);
    if ($return != 0) {
        throw new Exception('Simulation of votecount daemon failed');
    }

    // output standard page (showing next month's candidates)
    http_get_history();
}

/**
 * Execute script that clears all data from cassandra and randomly generates 3
 * candidates and resets the current month
 */
function http_post_reset_simulation() {
    exec('/usr/local/src/php/pepandlove-daemon/phproot/run clear-and-seed.php', $output, $return);
    if ($return != 0) {
        throw new Exception('Script to clear and seed data failed');
    }

    // output standard page (from an empty cassandra)
    http_get_history();
}

/**
 * Execute script that randomly generates upcoming investment candidates for
 * a simulation.
 */
function http_post_generate_upcoming() {

    // invoke daemon to generate random upcoming investments
    exec('php /usr/local/src/php/pepandlove-daemon/gen-upcoming/main.php', $output, $return);
    if ($return != 0) {
        throw new Exception('Generating random upcoming investment candidates failed.');
    }

    // output upcoming page (with newly generated items)
    http_get_upcoming();
}

?>
